(load "compiler-test-util.lisp")

;;; The perfect hash generator can process any set of UB32 values.
;;; For example:
#|
(make-perfect-hash-lambda
  (map '(array (unsigned-byte 32) 1) (lambda (x) (ldb (byte 32 0) (sxhash x)))
       '(a b c d e f g h i j k l m n o p)))
 =>
(LAMBDA (VAL)
  (DECLARE (OPTIMIZE (SAFETY 0) (DEBUG 0) (STORE-SOURCE-FORM 0)))
  (DECLARE (TYPE (UNSIGNED-BYTE 32) VAL))
  (SYMBOL-MACROLET ((TAB #(0 12 11 13 0 0 12 1)))
    (THE (MOD 16)
         (UINT32-MODULARLY VAL
           (LET ((B (& (>> VAL 13) 7)))
             (LET ((A (>> (<< VAL 5) 29)))
               (^ A (AREF TAB B))))))))
|#

(defstruct root)
(defstruct (parent (:include root)))
(defstruct (kid (:include root)))
(defstruct (otherkid (:include root)))
(defstruct foo)
(defstruct bar)
(defstruct baz)
(declaim (freeze-type root foo bar baz))

(defvar *transform-result*)
(sb-int:encapsulate 'sb-c::transform-frozen-struct-union-typep 'check-if-called
 (lambda (realfun &rest args)
   (setf *transform-result* (apply realfun args))))

(defun typecheck-almost-branchlessly (x)
  (declare (optimize (sb-c::verify-arg-count 0)))
  ;; the check for NIL and %instancep are the only branches
  (values t (the (or null foo bar baz (and root (not otherkid))) x)))
(compile 'typecheck-almost-branchlessly)

(with-test (:name :structure-union-typep)
  (assert *transform-result*)
  ;; assert correct types accepted, some of them unrelated
  (dolist (ctor '(make-root make-parent make-kid
                  make-foo make-bar make-baz))
    (assert (typecheck-almost-branchlessly (funcall ctor))))
  (assert (typecheck-almost-branchlessly nil))
  (assert-error (typecheck-almost-branchlessly (make-otherkid)))
  (assert-error (typecheck-almost-branchlessly #p"zook"))
  #+x86-64 ; assert only 3 conditional jumps needed
  (let* ((model (get-simple-fun-instruction-model #'typecheck-almost-branchlessly))
         (jmps (count-if (lambda (x) (string= (second x) "JMP")) model)))
    (assert (= jmps 3))))

(with-test (:name :minimal-vs-non-minimal)
  (let* ((symbols
          ;; Not sure why INTERN would randomly occur in SB-WALKER but it did,
          ;; thereby undoing the perfect hash and creating empty cells.
          ;; It's moot, now that I've temporarily disabled perfect hashing of packages.
          (remove-if-not #'symbolp
                         (sb-impl::symtbl-cells (sb-impl::package-internal-symbols
                                                 (find-package "SB-WALKER")))))
         (hashes (map '(simple-array (unsigned-byte 32) (*))
                      #'sb-kernel::symbol-name-hash
                      symbols))
         (n (length hashes))
         (expr1 (sb-c:make-perfect-hash-lambda hashes :dummy t nil nil))
         (expr2 (sb-c:make-perfect-hash-lambda hashes :dummy nil nil nil))
         (fun1 (compile nil expr1))
         (fun2 (compile nil expr2))
         (range1 (map 'list fun1 hashes))
         (range2 (map 'list fun2 hashes)))
    ;; Not much can be asserted about the non-minimal function.
    ;; It happens to be a function that returns a value higher than N for this
    ;; input set, but it need not- the generator might return a minimal hash
    ;; through pure luck.
    (assert (= (reduce #'max range1) (1- n)))
    (assert (loop for val in range2 thereis (>= val n)))))

(defun test-perfect-hashfun (fun keys &optional print)
  (when (listp keys)
    (setq keys (coerce keys 'vector)))
  (let* ((n (length keys))
         (seen (make-array n :initial-element nil)))
    (sb-int:dovector (key keys)
      (let ((hash
             (etypecase key
               ((unsigned-byte 32) (funcall fun key))
               (symbol
                (funcall fun (sb-kernel::symbol-name-hash key))))))
        (when print (format t "~s -> ~d~%" key hash))
        ;; Can't exceed N-1, and can't repeat
        (when (or (>= hash n) (aref seen hash))
          (let ((*print-length* nil)
                (*print-pretty* t)
                (*print-right-margin* 200))
            (format *error-output* "~&Key vector:~%~X~%" keys))
          (error "Hash was not perfect"))
        (setf (aref seen hash) t)))))

(with-test (:name :test-unicode-phash-cache)
  (with-open-file (stream "../tools-for-build/unicode-phash.lisp-expr")
    (loop
      (let ((keys (let ((*read-base* 16)) (read stream nil))))
        (unless keys (return))
        (let* ((lexpr (let ((*package* (find-package "SB-C"))) (read stream)))
               (fun (compile nil lexpr))
               (constants (ctu:find-code-constants fun)))
          (dolist (const constants)
            ;; This assertion failed when the printed representation of
            ;; the lambda omitted array specializations
            (assert (typep const 'sb-kernel:simple-unboxed-array)))
          (test-perfect-hashfun fun keys))))))

(with-test (:name :typo-example-1) ; of which there may be more
  (let* ((keys (make-array 5 :element-type '(unsigned-byte 32)
                           :initial-contents #(3739790036 1578584344 2172243460 496160493 696125627)))
         (f (compile nil (sb-c:make-perfect-hash-lambda keys))))
    (test-perfect-hashfun f keys)))

(defun test-|3,4|-coverage (inputs covered print)
  (multiple-value-bind (expr string)
      (sb-c:make-perfect-hash-lambda inputs)
    (let ((compiled (compile nil expr)))
      (test-perfect-hashfun compiled inputs))
    (let ((startpos 0))
      (loop (let ((p (position #\; string :start startpos)))
              (unless p (return))
              (let* ((nl (the fixnum (position #\newline string :start p)))
                     (comment (subseq string (1+ p) nl)))
                (unless (member comment covered :test 'string=)
                  (when print (format t "[~A]" comment))
                  (push comment covered))
                (setq startpos nl))))))
  covered)

(defun test-3-random (n-trials)
  (let ((rs (make-random-state t)) ; randomly-seeded random-state
        (inputs (make-array 3 :element-type '(unsigned-byte 32)))
        (covered nil))
    (dotimes (i n-trials covered)
      (let ((a (random (ash 1 32) rs))
            (b (random (ash 1 32) rs))
            (c (random (ash 1 32) rs)))
        (unless (or (= a b) (= a c) (= b c))
          (setf (aref inputs 0) a (aref inputs 1) b (aref inputs 2) c)
          (setq covered (test-|3,4|-coverage inputs covered nil)))))))

(defun test-4-random (n-trials)
  (let ((rs (make-random-state t)) ; randomly-seeded random-state
        (inputs (make-array 4 :element-type '(unsigned-byte 32)))
        (covered nil))
    (dotimes (i n-trials covered)
      (let ((a (random (ash 1 32) rs))
            (b (random (ash 1 32) rs))
            (c (random (ash 1 32) rs))
            (d (random (ash 1 32) rs)))
        (unless (or (= a b) (= a c) (= a d)
                    (= b c) (= b d)
                    (= c d))
          (setf (aref inputs 0) a (aref inputs 1) b
                (aref inputs 2) c (aref inputs 3) d)
          (setq covered (test-|3,4|-coverage inputs covered nil)))))))

(with-test (:name :hash-3)
  (let ((ka (make-array 3 :element-type '(unsigned-byte 32)))
        (covered))
    (flet ((test (a b c)
             (setf (aref ka 0) a (aref ka 1) b (aref ka 2) c)
             (setq covered (test-|3,4|-coverage ka covered t))))
      (test 0 1 2)
      (test 0 3 2)
      (test #x3fffffff #x7fffffff #xbfffffff)
      (test #x7fffffff #xbfffffff #xffffffff)
      (test #xffff3fff #xffff7fff #xffffbfff)
      (test #xffff7fff #xffffbfff #xffffffff)
      (test 0 1 #x100)
      (test 1 #x100 #x101)
      (test 0 4 #x10)
      (test 4 #x10 #x14)))
  (terpri)
  (test-3-random 100))

(with-test (:name :hash-4)
  (let ((ka (make-array 4 :element-type '(unsigned-byte 32)))
        (covered))
    (flet ((test (a b c d)
             (setf (aref ka 0) a (aref ka 1) b (aref ka 2) c (aref ka 3) d)
             (setq covered (test-|3,4|-coverage ka covered t))))
      (test 0 1 2 3)
      (test #x0fffffff #x4fffffff #x8fffffff #xcfffffff)
      (test 0 2 4 6)
      (test 0 1 2 4)
      (test 0 1 3 5)
      (test 3 4 5 8)
      (test 1 2 6 8)
      (test 1 2 8 #xa)
      (test 0 1 3 4)
      (test 1 4 7 8)
      (test 0 4 8 #xa)
      (test #x04 #x08 #x10 #x14)
      (test 0 4 5 8)
      (test 1 9 #xb #x10)
      (test 0 2 6 8)
      (test 0 2 8 9)
      (test #x00 #x04 #x10 #x12)
      (test 0 1 5 8)
      (test #x00 #x04 #x05 #x10)
      (test #x00 #x02 #x0a #x10)
      (test #x02 #x10 #x11 #x18)
      (test 0 4 6 #xc)
      (test 2 #xa #xb #x18)
      (test 0 2 4 8)
      (test 0 2 #x8 #x10)
      (test 0 1 4 #x10)
      (test 0 4 9 #x10)
      (test 0 3 4 #x10)
      (test 2 3 #xa #x10)
      (test 0 2 4 #x10)
      (test 0 4 8 #x20)
      (test 2 3 #xa #x10)
      (test 0 2 4 #x10)))
  (terpri)
  (test-4-random 100))

(with-test (:name :hash-3-brutal :skipped-on (or (:not :slow) (:not :sb-thread)))
  (let* ((threads
          (loop repeat 4
                collect (sb-thread:make-thread #'test-3-random :arguments (list 1000))))
         (results (mapcar #'sb-thread:join-thread threads))
         (coverage (reduce (lambda (a b) (union a b :test #'string=))
                           results)))
    ;; This seldom (if ever) manages to hit more than 7 of Bob's 3-key cases
    (format t "~&Covered: ~A~%" (sort coverage #'string<))))

(with-test (:name :hash-4-brutal :skipped-on (or (:not :slow) (:not :sb-thread)))
  (let* ((threads
          (loop repeat 4
                collect (sb-thread:make-thread #'test-4-random :arguments (list 10000))))
         (results (mapcar #'sb-thread:join-thread threads))
         (coverage (reduce (lambda (a b) (union a b :test #'string=))
                           results)))
    ;; The random tester only seems to hit about 13 cases
    (format t "~&Covered: ~A~%" (sort coverage #'string<))))

;;; Packages serve as a nice source of test data.
(defun get-all-syms (pkg table-selector)
  (let ((pkg (find-package pkg)))
    (labels ((filter (reader)
               (coerce
                (remove-if-not 'symbolp
                               (sb-impl::symtbl-cells (funcall reader pkg)))
                'list))
             (int () (filter 'sb-impl::package-internal-symbols))
             (ext () (filter 'sb-impl::package-external-symbols)))
      (case table-selector
        (:internal (int))
        (:external (ext))
        (:both (nconc (int) (ext)))))))

(defun generate-perfect-hashfun (symbols)
  (let ((hashes
         (map '(simple-array (unsigned-byte 32) (*))
              #'sb-kernel::symbol-name-hash
              symbols)))
    ;; if symbols hash the same, we can't test the generator on this package
    (unless (= (length (remove-duplicates hashes)) (length hashes))
      ;; diagnose it
      (let ((ht (make-hash-table :test 'equal)))
        (loop for s in symbols for h across hashes do (push s (gethash h ht)))
        (format t "~&Collisions:~%")
        (sb-int:dohash ((h symbols) ht)
          (when (cdr symbols)
            (format t "~x = ~S~%" h symbols))))
      (return-from generate-perfect-hashfun (values nil nil)))
    (let ((expr (sb-c:make-perfect-hash-lambda hashes)))
      #+nil
      (let ((*package* (find-package "SB-IMPL"))
            (*print-readably* t)
            (*print-length* 20) ; don't show huge arrays
            (*print-right-margin* 200))
        (pprint expr)
        (terpri))
      (values (compile nil expr) expr))))

(with-test (:name :exercise-perfect-hash-generator)
  (format t "~&Symbol count:")
  (dolist (p (list-all-packages))
    ;; Get a bunch of symbols, generate a perfect hash function,
    ;; and then assert that it is one.
    (dolist (symbol-set '(:internal :external :both))
      (let ((symbols (get-all-syms p symbol-set)))
        (when (> (length symbols) 4)
          (format t " ~D" (length symbols))
          (force-output)
          (let ((f (generate-perfect-hashfun symbols)))
            (when f
              (test-perfect-hashfun f symbols)))))))
  (terpri))

(defun find-tables (expression)
  (let (tab scramble)
    (let ((fifth (fifth expression)))
      (assert (typep fifth '(cons (member symbol-macrolet the))))
      (when (eq (car fifth) 'symbol-macrolet)
        (let ((bindings (second fifth)))
          (dolist (binding bindings)
            (let ((var (first binding)))
              (cond ((string= var "SCRAMBLE") (setq scramble (second binding)))
                    ((string= var "TAB") (setq tab (second binding)))))))))
    (values scramble tab)))

(defun random-subset (random-state keys n)
  (let ((result (make-array n :element-type '(unsigned-byte 32)))
        (picked (make-hash-table)))
    (dotimes (i n result)
      (loop
        (let* ((pick (random (length keys) random-state))
               (key (aref keys pick)))
          (unless (gethash key picked)
            (setf (gethash key picked) t)
            (setf (aref result i) key)
            (return)))))))

;;; To exercise all the cases from 'h8a'..'h8i' and 'hna'..'hnr'
;;; we have to use many different set cardinalities.
;;; Even then there's no guarantee to hit them all.
;;; But I did manage to expose some syntax errors in my translation
;;; from C to Lisp. It would be nice if the output constructors
;;; could be more stylish than just printf.
;;; Unfortunately the algorithm can get really slow on certain
;;; sets, and then go fast again when adding _more_ symbols.
;;; This usually doesn't take more than about 5 seconds on a good machine,
;;; but it's pretty random how long it takes.
(with-test (:name :try-various-sizes :skipped-on (:not :slow))
  (let ((hashes (make-hash-table))
        (random-state (make-random-state t))) ; randomly-seeded random-state
    (dolist (str (sb-vm:list-allocated-objects :all :test #'stringp))
      (let ((hash (ldb (byte 32 0) (sxhash str))))
        (unless (gethash hash hashes)
          (setf (gethash hash hashes) t))))
    (let ((a (make-array (hash-table-count hashes))))
      (format t "~&~D unique hashes~%" (length a))
      (let ((i -1))
        (sb-int:dohash ((k v) hashes)
          (declare (ignore v))
          (setf (aref a (incf i)) k)))
      (let (trials)
        ;; Generate random sizes to try.
        (dotimes (i 100)
          (let ((n (floor (expt 10 (random 4.5 random-state)))))
            (when (and (>= n 5) (<= n (/ (length a) 2)))
              (push n trials))))
        ;; Try those sizes
        (dolist (n (sort trials #'<))
          (let* ((subset (random-subset random-state a n))
                 (lambda (sb-c:make-perfect-hash-lambda subset)))
            (multiple-value-bind (scramble tab) (find-tables lambda)
              (let ((fun (compile nil lambda)))
                (test-perfect-hashfun fun subset)
                (let ((*print-pretty* nil))
                  (format t "~&~5D keys:~@[ tab=~S~]~@[ scramble=~S~]~%"
                          n
                          (if tab (type-of tab))
                          (if scramble (type-of scramble))))))))))))

(defvar *very-slow-example* (let ((*read-base* 16)) (read-from-string
"#(53530002 4770EA78 6AA3E1C5 B4CCFC8F A2D996DB 1E7F87DE 257051AC 60E75E3B 3E98CF44 71FF5BF7 6B9A8EC5 DAE927B E5DF5D1 2BE794F A00180A 51F0C95A 2B69DA7D 87C1FA7E E550F704 F0FF0702 D8094944 F49E5A49
  C1DBBF70 DAF99263 270A225 7CEB8354 71757486 61A1CF19 72BF08F4 8F5F4746 F5FEBECE D8BFC548 6C87D056 7782C327 BF7FDA67 F23E5C73 60FBC028 C0198E36 AA9F8E1B ECDFB6A4 7D439E91 1CBED4FE F6C89E69 5C474EA0
  88FC8679 7BF12F66 8344F203 6961DD56 392AF0D8 289324F 2D269C15 A657A9D9 C77445A0 61139BF4 309CDDD5 5791C818 BA2CE6F0 E9F87996 B627235F 7DC08AE6 C89D8E90 A228455D 78A24E69 52A60A2 CAE3027C 58B5ECF4
  CF88B072 68762154 FE558E02 4DB089F9 A9A89025 71D7E6DC BBEB286B 5A75849A D896A36A 535F583E F6217C04 D01072E3 7035D2BF F2EF9148 A05570D1 CB3AB901 6FA2CCC1 CD31EAB6 792E1B27 B212DC65 DC2AAAF2 B79B6E4E
  59D5B4E9 75C90434 F9C19DFB BC5CCB B5BA35F8 6CC5BCA5 F7B037B9 BA24080 F1BA603C 44C89414 CCF5FC73 91D51C64 641D268D D3760017 1426FC1F A94861B5 E3D3780F 57913A31 843E1283 3FF0FC03 4E9D4B86 13336292
  BEEC9A25 DFCCBDA2 AD5EE946 3099BC01 E2E48031 44ADC6C1 B13915D5 9C7A5355 55A68433 2D4D1AE8 7F67CCE3 D8DA7598 3DD3F5B1 153EF22C 383F83E3 5D4F1D63 3AFD405 C4684F1A 28AE06AD DBD8662F A55C0848 7C5BA2A5
  31C786B2 FBC63AA F6EEE9B3 19E0DFE4 A96083B 14C712EA 74306737 27C10088 2CBA8D38 74A5A83C 7C3BC06D 6F8342FF B4D4AC47 1A17330C FEBDF7A5 3D6088D7 65B5E48 509E9A6B 3E81E432 580DE040 D5744A7C D4435C4A
  37813350 892D37E5 B67F161E 6DACFD38 9B7DD2F6 EB7A1C51 D4A80DD 3E1543CC 44AF7973 AF25217B 57B1A712 5FFFFEEE B1D00101 F9F9B4B4 7B08E49F 54A679F4 CCDCE9BF FCC96F30 9004CE1C 5E438878 6F6B1E02 A10B3363
  B6E86774 C35B1008 DD5D73AF B2F9100B 2DC18005 5945C961 D2D81449 7F6516C CA64598E B80A7D44 704EF10E E66497B CA687F42 DA111819 FAF95664 372DEE7 2C3587A3 6B66DAD6 AD33C41C 60E1E3A9 3E528159 EB5AC890
  55921F4 D01D24D2 BC83B369 A8A4481B 2636AB0E F72424F6 707C4F4 9C8EC91F 88C564AB E8FAB71A 18075C73 F8788B3A 6B8201B4 99068C90 6F1CD912 A9387287 BFB49890 7C973ADF 4D3785BD 4331B99A D84FFEB4 27029B50
  6D993BB2 E2F354CA 508CAD36 5FF37F64 1C77C19A E0459449 7E39BA82 FA46D70B 4AF8B3FC 40331CB5 70FF5F15 9F78BA27 6AD2A2E4 E86C644B F172D2DE 8936B662 76CC3395 17F495E3 9EDCAC71 AC475261 7DE07F72 63381AA8
  22173E5D E28908F1 25B7B730 B7890FB8 C4949F87 ECDBCE44 C78D38F7 38A905FA 11DC63F3 9E6B7CE CC21AD71 C68002C EE05CC71 C5A5FC30 BD4D961B 4236FD4 DEDF9EB0 94B25038 8CD548BE 8991CB0B FE50C4A0 EA4C7635
  A3CF68D0 9BABE5A6 FDAFFF80 79015492 B48D84D6 5BFC7EC7 E852854C D6EE81D 7D9FCE25 C7A70855 2943A916 A2BD261 46F71EEA F0D792BD 8E4738B6 2159D88F 63205D22 40CA12C4 4276A193 A8292536 3DFB21AB 2CE4DD72
  11E1A1DE 2E31390B 4557C690 280608D0 9F3E49A 1B159745 795490F2 1AE18C65 86B8F8F0 A2E794CC D472822C E5E34BEA 9321559B 986B52B8 103F5FFE BB7A7D79 4B972446 71B0AC24 AB46D000 95F26AA FA52F839 44724490
  2547994B 75C56261 8C00D0D5 394606C0 5A0C4F60 19EFE9BA 60BD2C8E DA15A317 7ADCFE43 D93B7CA5 1045AA2D D9C118DB 50B7D152 6E2A5F0 22942672 798C55DB 8308A550 94BEDDAD A0402622 83F7AD01 32F0912F DCDE5702
  4B50A945 1685046E F73751AA 60935350 A7BFD6FC BB0D313C 61A84FAA C4DBDDC2 DB659CA3 523F25F9 612972E5 92616882 2A93B5D8 C52334F8 644C27FA 4199AA99 52367F9D 4AABB664 40E91B3B 34C9CA75 101079F5 FCDA9CDB
  F9551EA 66CA957F A8A31556 7609E426 BE1A67D7 4D4C12DC 7162AF19 5AC29EF9 204DDA7C 1BB778C2 EAA9A24D A6B1360B CC4CFDF 9C745EB5 C18148AA 66C5EB52 8A168EC8 8ADD28ED EA9B1132 28F6B2A 976A8FE4 42E86DA7
  85A80754 2FBFFC0E D3919FD4 3EC02941 671EBD5F 8991A702 1AA904A5 8F98A408 89EF3452 96525861 4460D961 98F28BEE A589B05E DD7CC02B 73C5E97F 8C5F3323 754B7B3B 3B50F441 79094EC5 61C64ADA B4A877C1 19F02F56
  C8DE5452 C6FBFD6 4748E4F5 A52AA6E3 82465E92 888BEF68 7DA46B62 C3FCE870 28864FB4 82513ED8 1569FC11 84415184 6FDC41C5 ACD32F58 A866A0F6 D44A50CB 2F31495B A4AEF90A EBEFE836 D0EC61EA FF384D35 13FF83EB
  DBB9611C 49265F6C B623D500 604F1629 178CCD29 C9FEE003 23783B51 EBA2BEFF 1CB45DF A1A1E92E F5B283EB 7C44D5A6 4A84222D 579A9C93 E6968CB7 1CAB1464 AB2C2A41 3A0A57C7 2FD93F22 FBDF2C26 27BBFB4E 9ECABD87
  CC05DFB0 DBB35655 5CBB69A3 4CDED7FB ED7EECF4 387B863A BA50FA9 B155F3E2 B86B4D0E 587D549A 16F2E858 2612BD20 53957001 CA742D01 F8C3DD10 261EB01B 991BFEFB B0C32E4A 652A2D5 35913791 5DF84055 C82B2D6
  4A2B36F0 D80C9C7 B8F27CA7 E5B231E9 14AA3576 A3E3FC6D 7A2F0E4 194CD011 A7F33E2A E2BB4006 599DE8FD EC83ACC1 606BE0A8 1F6D8D74 8F34445D 8DB4BCED AE32084B 67F597BF 2C087419 90A4F4AD 4901FE48 87E95FAA
  683B8815 41B9ECDF 38EF6FAF 4779C389 976C7EE3 BB713C57 F6FCCCCB 81FE35C5 3C5F4337 4553DE6B 1623AFB7 72013634 B7657924 F05C85B7 AD9FFBF F18F29CE 4C0FA007 9646F994 DED04597 77D35499 34971264 F0ECF497
  92BCFA20 AF8DF370 A24E3D96 BE94B5BB 742521A3 D76419A DA4C0D9A 2122604E E618ACAA 5796B3BF 24797206 59DB0D14 1B6DC7A3 71105EF4 6365C59B 65EFCAD3 CE544E96 1658E38 6EF25800 117D5932 6BD31ABA 7110EFE1
  6AF7F7B1 48B0EABC 71F85935 C43E771D 217A9A68 8D5BD374 43D33C65 17740826 3D6DDEED 32EEC85B 40AEA002 34CA5B43 57B09B0B F0880E0D EE4A093D B70013D2 7B73D8B3 2A004CE0 38510F6C DA991753 E87151F0 3D065893
  14DBF60A 8EB05028 8386DB57 80B9F01B 8ACF4A96 FB96493D AFDA2346 2BAAD6B1 7874DEB7 ED097B62 CBF736A0 6B620970 C418072F B0B7ED0F 78549915 F5F8F4EA EDA1D5E9 B27B9C2F 61AE7F3F 4F026784 C28C87A0 DB91549D
  37DB6A79 CB096687 ABF2CE8A 94576769 5A67ADAE 6579EF67 1502BA30 D1446B70 3890AD47 3F70B03B 189BB58C 5C29A00C 9A51931E A6B3F67C 49296896 B65E4934 DDFCEFFD C1966492 4F16ADC 8387C9DC 55771711 89ECA2DB
  A689103A 4A33BCD5 F0F7C126 394EC051 6ED671D7 8C31730F 366F7C0B CA35CB29 E1111A47 EFAC6C9A B588378F E733EA1 1F4D07D9 61F8AADA 136D1159 5F2DD80B 6231ACB8 5F678207 A8EC4CF7 5219DB06 EFB58E85 BE779E98
  E96128C1 3F914525 2D0BDF3D 412E539E 46DB5241 DD9F379 87031B19 FDF974A4 1315A89C 2A7D7B43 5228DF28 B2A9FFA2 6E0F62FD 5EE2B659 E02F487E 6251940A E7907B94 D2FC2BBE A6B312C9 D8B7F51F 5203B39B 7942E126
  29A476C AE258A4 1994A972 1AEDC1F3 7BC8E77C AE97B034 116E098B CDFBF020 1818712D 68F37680 EF26D6B3 44B68CC 789AF088 4C2256CD C33007F3 36E57B46 C747F339 9DDA63E0 EEFA5D75 A2ED1C59 3173AD00 91D9F714
  D9FAB7DD 1EC247FA 8D5F5D44 82C61957 515DD663 2D396E71 CAD73990 7D0AF71E E3512FBD 6CB14056 7CF83F50 121B24B5 28909ADD 2692C214 12B6A67B 60851B74 A1FB09B A3BABFFB 8BEC90DD D7F5C3D8 9CB2C470 320A0763
  C69879BB 68ED9C5 B1EDD193 83D14308 7B3047BA FAC56C60 686D7790 70C8BB1B 472FC747 81BA64AD C18CA5D6 C6C7761B 85CB1F8F 726DDF0D AA451F68 70A3B667 6530FEB6 292F9B7B 7CF4DFC0 6534FE09 343833B 5C3CD5B7
  BD7D6960 413E3E8F 4B7906C9 2689E49B 2744CDA4 94301E46 7839CC1D 7860AC5E FDCCEE36 B5761AD4 EBE31A96 39ADA73B 6494C55E E13A70E0 3D5DCB1B ECC64742 39253B63 58031BE4 6B9009DF 217D9D85 D93DA357 DB7D9E3D
  8023ECA 8ECD56AB 9963BFF2 94A4C12D 1687247D 13DDDD8C 1842D3BE 1852F24F A4BEAC76 499B8847 3956122C 94A875A8 9A012E17 751F13D2 908E400 C2C83833 6028BD41 1A3E0268 62AB699D 21C1EE1F A74AAFAE B4E89467
  FC340449 618BC1BD D7BBE401 40DC78D3 E2F6B7D1 E5C5D90A 1CB41C68 937E8F73 A799AAF1 AB63E7E7 E492247F C5F8900E C8347A71 3ACEA427 29E9F064 98C7219 EEAB6757 25849191 B3A462D 12FFFAA1 B94535C3 561477BB
  6BBE0C07 A9644350 BE9B8E 24D0B47C F7600A99 3135748F BD48359C 4E644050 705E5183 3F62ADF0 831775D2 9F9577E0 E32AC0E3 AE2A8035 3449AF9A 149186E3 17EC7451 39DF4E11 2190DA4D F10BF3AB 5CF09883 F43BE5AA
  878B86E2 BDA7FDDD 4E6198E9 3ED4DB3D 9114785E A57BBED3 679F01A3 F5C07340 9882734A CAF39BEF D2C35439 30FFB97 E5F33F32 FB904E23 E98D6CC9 3E3FA3FC 51AC5036 F3B33EF4 D393D436 55AC880D 35B1C1D2 611FA57D
  ECE938AA C1F7FC7B E1B112DF A8533D7 C049B421 AAB84E29 27A957C0 1F9F4B38 5FDEB1EE E9F6BB2B F85B88B8 C9580CA7 B30F0F61 FE68D2C0 4B59E3A5 DEDBEA9A 3F401CD4 DD0ACAAE 5CB96D05 EAA2E46F 6201E4EB 7341DC0E
  8A434E9 BF37BC56 C44A5020 A51F088C F75C0242 89FC5105 B5AA866C 40353B6 31B62AB4 CDB9EC23 C7A6817D CD3FD2C AD3ECFE7 A510F2B3 FE0C19DF 1A4DFEA0 4137B5A8 8362A509 406CAEB9 29AE3EF0 41CE3D9A 6EE80715
  99D48F42 5EBCE98 5AAD75A1 C2587B28 DD98439A 70C87C27 811494FB 432A6C7D 3CA2C3EF 2E257AC8 91678BBA F753D8F0 74EC28B0 620C7F89 A4A930E1 8E458E53 A2CD005B 72DF71E7 100E6E97 3436EA34 D16E07AF 69A45B1F
  37DFE045 388EFC06 5779754E 750093F4 FF3E4E4C 5920F89D 7ADA65FA A0B75F9 C9782167 DA2C03E7 5B756C7D 445A3B2D 1FD299FD D7471542 627E4EEC AAB0F3DC 70782BB4 6807B869 F0073B2C FE1B072D 8713039F 7CB578AE
  C7893555 7C79C3DE E0216F09 EA06305E 96B03062 A2E0F2EA 642A2D45 D6E303FC C39196EA 9A982092 2A535386 CB96E0E8 37F7F77E EAADFB36 4242FF1D EACE1F73 F166045C ECF197BF D1C52917 AEA574C9 61A7827B DDFA441E
  537D418 FF54CC49 8A4A0D2F CE39DD7B 61636506 191489A6 C5DAFA55 97BA4A75 EF1C18A4 5CDBBA9D 3AD1F286 49E1E917 7A23D23F 3E61C34C E3DC76A 82F4473 D13BD571 7D8EEB5D B4F705DE 140D5CA2 4ED1BB33 51CC7423
  38E9F9F8 2A969030 4AB3EB80 4A8BAA29 F8105A62 C4E06F5D 5990044E 721A24F4 24596EDD A6D61EDD DCE629 D5DBC4AD B2986DB 7182F720 7018A0E8 D4E63D88 C3AAF4FA A218445E 9A77828C 6EC518AD 75A5E851 91289EA
  FE725633 504FC343 CCF27089 911B9927 20A0BA60 7B7CBEA0 1A1A2460 DE1B97BE 59E6C18D 826191FE 381B3163 57136C83 75C746CF DD709C9B 4C1E7BC 1056CBE4 7A88B1AF 8625403A 7DFDB30 5E5B7E4 7EB87253 E5B15BDC
  DCA1F351 36870E63 CC9728D5 8EE5B581 52D67423 304129E5 8C4BC39B 6E5E8B1C F6046378 8E923D46 D0F30B0C DA7851E1 6F9E0E82 5251BF74 D29F6051 E63F434B 6931B41B 53E6983B 6C8A42EE 70B6008 CE409345 42DBA192
  77A07A35 B153FEA0 54532E0A C869E734 6964AE0 4D889ED1 14671C6B 4F1BD65B 2FFFAF55 74EA9A95 FE2D002C 180A30E4 1C475861 15D89CE5 A9346CFE E370D4EB A3DE5EEC 2BD0CC6F 202BA0F7 869636D6 8DE63986 E8E8A0F4
  F7C659B5 C0B56B78 BDF2561A 33DE5522 C21EE7A7 7C935BC1 30CFF6DA 174BDD0A A6453818 EF45131D 929FEB27 4A0F3088 957C44DD ADD363F2 8851FDE7 64D41D08 649F0C6E 4D4BE3AE 421599B9 2ECE07D9 AB0E4F16 882E4BE4
  D81C6F5 F84ECBC4 156DE334 FF4532A 337D14F6 ADB8F75C F37D14DE 2AB32A29 6FC17D71 623C7F92 90B0C669 344CFCFB 3BF450FB A2004C4D 9F55BC20 1AC99479 8BDF79C9 A5B35E3E 203327E8 79BAA8A9 BAABCFE5 AA1970D2
  D1CCED51 DA79E2D5 F639DF9F C020DE4A 2F9E6F2C D3B80F24 D51B1E18 5732BD3A 5234942F BBCAF6E4 B38C8FE3 76019EC 8DA76432 29EA85FB AE8F548F 3BE61179 BD01F7C8 9F4A5FC3 827BD407 7415DA5 51A27D33 574EBE77
  5FEECC38 2D007BBA FE815D4 4CAA6F22 7F63A893 40ABA51A 6F853508 D6A2D6C9 DAE9B59C 60E26E7E 30FA439A 1E012D54 A408851A AAE937F2 BDDE7468 9A643798 C6DBE6DC B9C8166F 6906CC74 E38E2060 44F9D6F2 8ED916A2
  82723C6D 4BA18259 7D497263 38896916 21FECA5E 3BE72320 4FA9EBD3 9E892846 81327B69 45A402B2 2000428A CDC4253D 86A3B714 ADEC5BD7 C71817B6 50572D95 CB418998 5AC884AB 299C53C7 26AFB9CB C882E357 CD0C7E31
  818FE555 D36ED9B 75C462B7 16A1C28A 9DD52DC6 E9AC72B4 1B341F62 7326AAA6 2EB7BBFC A1EB51C6 4598FF74 3217A847 3A3F1D52 F906DF25 35C699EC E39CE81C A4AE5A22 BB68F3D0 55C26CCA 3F20EFC5 70AA5D58 F8B05877
  6CCFC02C 11AEF38E 906086AD 5AD10892 4CBFB607 3C3E1D22 2B0AB9DD 1413EC63 2FC2BA31 E4BC1205 DA39A4B3 18082A99 3C554A54 847E70B0 2F922BA4 D0B4C425 3D0A95AA 1C87D5E2 6ACCD849 A2276DA9 629D58FB 48B97474
  F39BBE05 339E00A0 97E01918 C8D5CF5 9F670856 F5CF6617 BFD613B4 FC8EFECC 890E99DF FFC8FB53 87F235CA ADF9675D F3A8F8F8 3B729679 F948BEB5 1F325336 812E1F5C 4787E4C A078B350 B1DD28BE 32F69220 1E48AAB0
  1AB6153D 64571C3A 53E56D88 9DBCF8B9 28B5725D 4915B6E7 76E3D6E2 D9875A08 151A3D4B D99CA704 D1F262BA 4E5ADC3E 804342DD 53BECF00 DD66FED0 53D9BB68 F43C5BA6 F4B419C5 232BF0C8 B021F027 A624374D 29B01002
  F8A8AC11 1F76703C 15BB438D C8763082 A1FCF299 32DC80E3 32034621 414DAF7E 1530FE4A B82DB63B C5D6F80B 4782CC8D 6898C3F8 B8256F70 3C6E1947 6F0CDD95 953DF195 A9B69181 E029699 AA2B5A94 2736C4A2 F32939D4
  D52E0941 F63DC03D 2E73A033 FC7337EB C84D323A 3C91EE62 985EC240 BF731C81 B5BD9EFE ED6CBDA0 133087AD 4B01DFB9 376959B5 40C63B43 B8C294FE C0EE053E 2043198 E7946215 68B1C8D E77854D9 D9CD9708 9D153612
  89EB3BD9 8D85B53 139D578C 3C7A9E11 340FFF3E B3EB584B 34187386 DCB01B79 365F7C81 145F44F1 ADB320CD BC66A374 A36A1BA C685D67C BDCFC8C9 E07D9741 F406241 CC1AD0A4 AC24CF5F C2219185 F65BB66B B5953EA2
  25035EF8 F4888450 167BDDB1 F31B2A0E 6CE1B57E 4349FD44 5114BD12 633AFE2E AF168938 6F474A0 86618CC 2418AEFB D3334FFF 47DBF21D C10B5390 D6998FE1 F193276A A608D822 8ED93636 5EE2ABF8 204F3A7 FB8FD23C
  2C62395E D38EF2FF 473B8231 DDFAB4D 3F1DA61E DB8D0402 520F577E 5B0CD4A3 7AF9CBB EDEC5640 65BDB98B A873B9D6 BA20776D DB1D5E18 739C566 61FBFA96 6235F78F 244CF44A D1A33DD4 B797A3CF 69AD785B BEC1D880
  7162F1C3 8D46238F 580F754 4360CCA8 C1C80756 51B7CAC8 35B6F330 4CC8F82 28A2D44D 8326F365 2DF0D340 3CC7E364 8193E977 A184BB77 93B4297D 3466A795 31F6303 9717A0A 46BF6C8B D99ED9A6 4088A457 BAAFFEC9
  31FB54A8 9110ECBD F10BB5F3 27A500DE C0E3FB70 9E81FF52 10B6CE88 D40A453D DDBA235F A77DB36A 9BDE06E4 B5DFA157 2A9D4233 8AE685E3 80C4D048 578D5ED5 42D2836 65DADEC9 27419152 5C302808 FC9D5407 625CB758
  D935511 5256326E 6CB5D8E4 6205D65B 87D52068 525040FA 2208F2BC F15207A7 E3D9D062 1B202B01 89ECFC06 62D139B7 780BDD80 D900BB9B 4894A8E8 CC7F27C5 4A58503E 7E31FF84 7591ECEC BF3B5CC8 14CBEBDD 3E75DC27
  48081 677E784 61D90C46 2F6A7043 C5A85403 767164CA 98C3C9F4 B613ED86 6848DD9B AD684246 591F91AF 1E95895D B26A1853 70F06C26 65DECA81 16728CF8 EAA5BAC5 8E5BBDF6 D100073 CA7B6935 D3D1E56A 4CE9F7F4
  4C009884 871C531 21893C96 86C598D7 FC0820AB A14B20EF D07DCE5C 53DE2B35 A3719F26 55C0D390 25133526 3513DCAE C41EF80A 13ED67C9 B739620E 15FDBF71 E923B611 14EC4774 B4FDD0E E4E1FAA0 422FED2 2A7594F6
  C67043D5 8733B977 414BA622 EB26ECB9 3F76C8E5 7B252CD6 A27EEB90 BFDB7E4 59DFAC33 711A9C54 CF3C1672 2F7F11F9 5950CB22 141EF437 5F556C06 E9099B7C 1F932F4A EB2036BB 66A142D9 6C2E816C 92B9D870 BEEE4005
  9A65E408 71087960 9207E96E 20A03C49 EC5D4301 92D34EA5 1A657DD 697F43FA 675C1C98 7D657715 B720D89D 85EB35A5 6BEBBBFC 3855FA9D 71552BD5 47FA9C5E 9C254812 C9E4DC6C 486F59AA 48455B60 4B65E130 8B3A7C9E
  4806C681 8F7344A3 3925464F CAAD235 CE9462E4 6AF75A9B 2CC141E8 2E761E59 EC5F9791 D5E9037E EA3B13D4 758B9160 1F3E8D8F C64F0149 3C8D6F4B 25A71F04 C8ED8590 8260CB2C 462502CA 526CFC1A B30A6E89 525035D0
  EB52D6C8 A2A7E265 B7F0DB0D 82E6A7D4 DD51A9D6 EE7862CE BCF88E99 4B3AE273 95219442 5709C0DA D6357F62 31D11FB 8D92ECE3 D6BC076E 283069B9 3F0904C6 FFDCAC52 C985F223 FA140BDD A741E356 477FF6A6 252CA166
  D98DBBA2 97750DC0 CD3DD654 4935FD94 71D7448D CBFC11FD 1B92242 2C4A18C8 14537F95 57043E10 416DBAF0 DB2BCAB6 1BAE2C4F 4642B0F4 BE0B7A71 F6AE2A5 93FA091B 46DD8444 92033A1D DD5D2735 FEB845E0 8351694F
  368300D7 402730F0 E90DDAFD 2A934CD5 D2558776 F4329F4E B1E261F 1478C519 B8F9873D 74C9CBEE DA32A09E C942657F CB751D2D F7286816 BC1D42F4 AB3E41D0 7DE4CDD7 C523F61F ECA896F6 19305778 CDA54E26 19F7CF81
  5608EB7D 8970E774 9069D366 106D00AF A4EB9952 DC106040 539AB7FD 25F0E72E B0AF98C8 935D1A85 F9EE462D D83B9B9C DEB886CD 699F5344 3858664A 9E4FCABF 96A191E6 8865BEF8 542AFBC6 A284B913 4BC3C78B 77D05C6E
  F82FC348 BF700182 75858F74 798349D9 C8ED0FF8 D0EF335D D8777386 BEA72827 34D5D5AE C8DC9BA9 1AA716E0 CF3C5103 DC7D1182 E8A18D48 59310A92 C896611A 3860F0A7 942A1604 953983D2 28395121 3A864860 B8802F40
  65832FFD E635B571 593F0D40 AC934B48 34D6E851 25594E35 A44DE95B 1FE05A7F EA42E56C 8EA9B5C2 CB4EFE54 7D3227CC 39B01DBD 696A76AA B17ACBD9 A07DDDB7 9932CB1A 253AC5D8 4AC37B9E 62F5FD95 4D4C857B CDBEEA42
  C7A001EF C60983C6 4818163C 6E5BEFFB AF49853B F098C9BA 8FB14568 274F4CC5 2CF870C5 6D04509D 13CA57DE AE9F8345 48E0AD0E 36BAD087 BB5BF78 31A2F352 5F77112D CDE5150D ED71EBF8 D9A39DE7 1A0C257 746FD7D
  2CC98C04 CEECBAB5 496C7509 1D6F8DD4 BFE6E7AC 2E91CA3E B85D52C1 5E6FC3FE B8C2E462 5C889C4D 4C379116 4F57E102 3AB78987 EB8C4073 C46081B4 1B8AE108 FB02C63E F6007062 4D21C2E4 6DD6C486 4DD73ACC 44BC5F4A
  F00E266F 285D9243 63BB5FE5 B4EF8E1F E0B70D17 3B1F30B 9F8D01D5 E873D66A 7BC359A6 ED1F5687 AAF2C7A9 12A16E12 B12CF157 F5EDF719 A20A41E F499081C 23A03F0F 914E453F C96951C7 BAFAAF1 F1C456E2 2B54F55B
  654A7FC3 491EB6E0 1E638EAF 3961134 6C4B8DAF EE1DE3EA EC2DA502 E3FA3C44 EEEC4768 EBCE51B4 C76723F0 34E39A17 CDEA8D11 8665535 BC354F7A 77ADBD74 505C5210 F83A8DA 11DFBB1C 8240D414 EFBA6A3 6BE3AFF1
  3A0CDB2B D2C984CF 2F17E96C 18CC23A8 C5E7BCD4 1C32BBA0 DAAFAFB4 C05C4A3 1FF27D4F 243AF1BC 1D2EB661 3ABAD302 34B19B47 B7727322 6A9A79D4 52A529B4 A122FF4F 5938E567 8EDB802D 951FC1DE 21EB1448 ACD74E57
  C399623C CF8D7729 9FE29459 EC06D873 F3AD5359 B5B2FBDD D0F8B5F3 1B2E590A 4E33D8F0 5391D16 DA613B39 95B99AC 946A0D11 49D547E6 DF7467B7 58389645 424321A8 FFE289C0 9BC02B33 57CAFB2D BBBB106F 9206C348
  2EC4942E 9DADB40 C173725D EA8B792D 747EA72A 4600F6A9 D2D5DF9 4FE75CA9 17C1F602 C8BD9DF4 2FA701E4 C3412A49 868F68AA E80FB23 D3498BFF E748EF15 21573994 425E85B7 642EC16 C2789CFD 95BAF85 FAC5AC8F
  347FCA11 7A82400A E55D5CA6 F168C2D7 3EE65213 85F0037D 1652DAB9 DC6BC6E3 3808DA55 A0DA26AF F8A7907A FA357C1E 2553A12F 11408679 58EDE4AE BAEC8012 8674E10A E70CF65C B7359E8F 7D0CD341 D2C75724 29015B7A
  F3CAAF94 C41275BB 25B5B009 7C41EB56 A24D10E4 549601ED 4556CBFB F6C74E82 DC1534C9 43D7CB4D DE0F051 AC6CADF8 1E9CAF83 80B1F858 831602C2 FCCBCA78 1D6289AE 5135D9C 805EA3E2 92444CFB E0EC4B76 45C1BE12
  437955FB 5C2F331B C5697FCD 6FFB5B8 AF147D43 B1A6F5C5 33FBF675 358E2083 C3CCCB38 5D0F57A9 5A70DAF4 811A9081 FDD64DC6 24C5775D 87590E08 2E533D41 A399F10C F2686B79 8F41117A D392425 5F4DD916 E141E59D
  A0D33620 C515B68C AD084A22 726A3E74 ED80AA15 11213AD2 73766AF0 234EECCD CE329A71 49145217 713189D0 511C275D 279685FD 3800B49F 3DB819D0 6AE813A1 F7F609E4 4F62ACAC 6C1BE231 FE44EF27 1DBA4058 B5F235E6
  84AEE43D F8FC77D2 570FAAEA C276FCC4 12F2831A EEAF2B75 D85FD32E 2F124924 CADF2FBA 2FB0B3F3 F47023F3 AB08E319 6FCB29DB B8D0725 DD0ABAF3 9566218 CF55DC64 2DB374DE 3E92C136 D0A053D1 80A57AE2 BD1C34FB
  289C56B1 249D93AD 59659489 B1D401BA 404511A5 C74830A6 FE24897 6E8ACF8B FE094466 3C02CB3 F3F55C0 D499ABF1 4BC93395 CAEA0FEA BA3BCD0 ED762362 ABE199F9 D37973C5 FA64C8F1 99927C4C B35122A7 744773F7
  8858A4FB A82F3B6C 64EA4446 30F484F7 5329B528 FA9FFEE5 3CA1CCA FCFB7178 3340EBE D6DA4C5F 82EBA48 C0F159D4 9C26EAF2 C42DD118 DD15FE32 39F3E5FC 16FCAB1A 6CD3727C 7C810D97 B165D065 B11C96CA 8C12F40F
  4964558 AC749D7D C64BB790 86A5C8D4 9570585B 7D84BA30 8071AA59 B0BA3077 CD9193A3 6E2D713 CC91BC9A 73CC9005 E1B4819E F2E49A9A 5E276705 423AF440 B4F0AA77 935E6249 508CF58E 64B5590A 880A6F9C C2DB85CD
  BFC2DA85 18A8104C 6CD53E26 BF7F5EA1 F48B157F 327C3FF9 9F5C5863 8172D481 11785872 5F7B918A 18D8F538 C0DC6BB7 462EE2B9 63C3B3AF E974FF33 173771EC D4812335 424EB3C2 49319166 A8043A1D B7C76A00 B74237CE
  7D9BCB00 EBA5396B 3EC9B01 12317805 8AFB239A 2FECC422 406300AF 7E4116D2 26FE9ED0 D7F4907D 440FB46E 1D26B7A9 1FDD6982 24DC1148 4EE09696 7F390A9A 3EA582D9 16BE5986 97AE1B15 85154E54 8F3E8090 B9C48A72
  226F94D7 C2AB0964 30695088 36196EA 5269D77B 1B18BD26 EABEAB6 971A9EE6 3ED441A3 AB1A3392 244259AA FED83871 D94464AE 98FCD085 CAD68AD1 A22D05BE 1E220AD2 1C95C39 DA5F55D1 2FFA8072 56E1A4F5 56016367
  7754B74A 18C5E4D8 15358059 3A4F5124 CB386B47 5536148B 7B94CC93 DC505D3F DE66022B 6E369418 17F4B005 7560F8AD 76BAB3D4 451F4A01 2CD3E08F D01066CD C777E53E A1688A2E 79196D2A 8CAFD01E E028006C EDE13CCF
  CC9D6D24 874FC986 972D01F 40E55082 E606EED3 4F8905C5 F862B1EF 7F3E5F0 C568A04E F07F7A2B F4D51834 76382C1F D9BE5FE4 A28651B4 61193B3B 565F4CAB EF8CDCDA 149A44F2 66C83CDE 63E7BFBE A9920E37 3BC67803
  34700300 194C61B5 589EC0CB 4927CC0D ED3B7EE3 52AFB8FB B37B0CD5 C2E065F 36554C70 EC6E6FD0 4493915F 8C9FC43 266E4661 34024431 2A7E08CC C7CE9460 42F06A52 5ABA3023 42FA59F4 F98223A8 ED0D0FB1 E74A7E98
  2E71AA2B 939B1CAD BA7AEA1F 1A759B87 7893E6B5 143CCAA0 F4273D5A 77CFC65A A2BC0EA8 50158ADB 390B123 662F28AE AB1FAF2F F742B710 4E50E5B4 A2C69536 E82DAD18 6D6BA151 B97F025C 5A23E649 FD2B322A E8C475E8
  8CB7D8BF BEAE9067 61D5B405 8A45318D FBF559BD 3D619C1E 2857752B C445FE3 AC8D7C1A 402323EF 1CCD8887 19AE10E6 23D893DC 50E78921 6E4CEB93 83C13FCF 455A623C BD038871 CF40258 28A1E0D0 4C78413 A91FD8D6
  D46A884A BD6D14D BDF1A97E 96A751AD C679FE3A 9C0A180F 9EA808CE E9E84222 65DC1DC9 FE20C81F 2E5E6260 C18D84C6 FD1AFB20 E6729A89 1BD52D1A 53968CCE 7053C412 DFFD4AC2 D36AFACF FA91B37B 1E7A88A3 935BF4BC
  C0243F90 9B8DC183 E4425023 65D0287A D0B8760A 48D54499 4B2DCF71 57BF3C6E 8EDC9C0B 2504339C 12E87CDD 17796C9C 37994396 1001808D 634901CD DDE37833 EF2492F5 28381B3F 1FAEE593 2E56D534 A0EE73D6 ACF13153
  ACF6024C CA18E609 88445BEE 1E563B2D BEFA4789 C5D783F7 203A7371 97B84CDD FE5310F2 14E7F40C 429F0E01 428603F3 9F93404 7E7552C2 11EF452F 4512B3DF CD951EE8 C3596133 A6AF725 3AD57D1B 425A0DDE ABBDF1D
  615679C1 90074973 37B8A654 5D824901 6A436398 82DE6FB1 524EFB10 16578FF3 F1A51DD1 B281590 11049595 4CBAEBCD 1010F899 B66A1CFE 9F83109D 80D60816 B1AD0B98 A93898DB 629659EF 1246ACFB 734009DE 3A35ECD1
  AF5D260C CECBB6BD CD9BF6E0 34358A25 8F15D96C 1546C047 95BE6D F13CC6C BF720712 4BEA5DEE FFBF74E3 B7B8B73F 2306BDC5 1F3E3D2D 9089864F A3326F24 D1B9C47B 1BAAF7C 743D69E1 5E5B0852 5C25FF8D 5487B96E
  C619CBB8 4B51BB5E 6602E16B 4521B78E F615A92C FCEB6492 A346BFC8 8CF0BCE3 18F0C00D DC7DEA11 913B0DF7 CDF242EC 5D37E618 37CCD58D A873BDD8 65A57915 1FB30BCF 4213681A ACA4017F 6756B8E9 932D0FD7 1CEE1F8D
  68E44D2F E8BC0483 C64FA823 83645BF4 46B64E11 4D017369 BE98FEA6 353A5DB6 8ADBE08E D7B2E691 4BADC6DF A5E2F8EC A4847ECE 661489B0 25AA92BD D9E40D1F 16AFF0C1 B4D3FCFB D8BB10B 5BF7FB07 1EA7295 B351AE0E
  BED88A2A 7D13F5C1 9BAE1B87 36A5F4FA CA26B699 36B27B5 44A76F97 C5F0B77B 8E052FAD 4E141C80 A84149E6 B84B76B3 C4C1E644 254E1B10 708E7650 EB8B13A1 71C89517 B5C00442 DB26EB07 D1539245 C563CF01 1F53872
  25FA6718 DF78ACA1 8698A83B 2E30024 33114CE0 123E3F27 CB19632A 7C652A4 2BBF9DD2 E99F40BE E2A5FE39 6159B264 379AA362 C9C3606C 3F5DCEFA 3909B4FB 54FD7A09 A97F1608 63798294 5E411BC8 AE0B57F5 41656C0C
  C939A662 609F6332 BBFB3313 763B995C 16FBFDDC 77DB38E E377BEFB 8D80C94A 537D4B5B 7B919821 F6BCCA54 37FF0FEA 726EDBD5 7215D2A4 5EA3E773 2B3AA401 9BD4E06D 6FFB8DAC CDE6D527 491F0532 66D5BB1C 97A99253
  94013F37 55CEA4AA 13CB851F C67210E3 6C93FF71 C15B8DF3 C09B2BC 4730921E 86FCD195 45CB1CCA BFE43BD0 6DD11351 23442065 D998F57C 3E334650 7F2DA5D5 82102D27 802DA4F6 DA05E3D8 875F1B32 FF16B8D8 38DF0EFF
  500CC153 3F34585F F88D8C0C 7B730903 AC0CD6C0 52B6C95 B5F9A85B F7745845 74CC7D2A D6809259 AE87B520 87DF484A 549E21DE 9307ECFE 225FC3B2 7DE5254A 74BA1719 DF97CF05 941469E7 5963D40F CA39778F C8F07536
  BEC30FF5 F6231729 E27D7B60 58113B27 5E027FE8 279989DA 7201B596 6BD3A212 61B0DB64 A52CC0 80B33A37 2A46A85E 1A255AFC CA4ED820 3008B271 1FE14ECE B098AF6E B1EB37B2 5A002E8 6E443B91 BC70F568 AF5D66C0
  949A9451 947633D2 E14A381B D222D7E4 46093533 B099A335 2628FA03 CB7494D7 46594919 55854E51 CB291CC3 447941B0 ACB6C62E 9063B017 3F43C708 1E833417 B9E96C98 1A314F28 C932920E 33CE029D 30DE155 81BE0F6C
  EE2D99C 15FD1093 7891FE1A 381F1F6D 49FB0959 BA1EF08 89242B74 89AD4B62 B1ED63E5 596A104E 9CCC36E4 46DE19EA 3108AF4E 3B596270 234E986E 9D85890A 7FF0B6B0 ED1FAD84 671ED0F4 178A6CE1 2CA0507 57C73EA9
  EA970A11 A2087919 1AEA894C 47D2EF85 1D4A7793 DBF9D5E 5E47E152 696471D6 E670B9A6 14209476 D9566366 BD11B494 4B2EFE9A 38E9A5D1 D9160EC2 FA25A0A0 FFB7EBE8 A59945CA 80452874 A7417383 1C889954 D53CB18B
  19FF95E9 B2E8C8EA 7167B2F 4E91E73B 8329314D F244F88B F00E7EAB 18F546A1 C601D29A D13D694A F03B4D27 5C531699 90321FD8 E01F5B03 4410DE19 18452280 6F77A8E0 A46B08D6 EE24ECE9 A63DFA1A 3520FB8 7138AE5E
  40AB96E4 E36007DF 93ABEEA8 87972A0D 8A1E000C E5BBAD2C 8E874344 4C66BCC4 E0688A53 13153E55 6D433FEE CC4DAC9B AED734C0 5BF749F5 9A648E6 60FFF226 4462B494 2807ED6 76E6A3B 3BB8082A 914BA226 F927E8F4
  E3F01E52 A4B899BA 66934AF2 3B6194CA E3806033 4CA6D307 6667EE5A F0BE3F4B 55473AA3 3D353473 FAF1C351 44C9285F 3905D784 73BB4542 BB4AE0D6 395FDBDF FBCF5644 4C8CABD9 D2535A3F 9FD7BAD3 975FDD46 D5EA36C4
  68AF1A39 BAAB0AEB 76AF34DE C1711B3 6A8FCC 4EE9B522 D3D79F02 12EAF2D4 24695825 227588E1 46698804 A348352E B0F75F01 EAA73E41 7947E7EE EE030159 B44EE330 1D63579D 11693062 7CE85C88 2EDF12B4 6410956C
  9DAC384D 48B995E7 10A2C969 467AD37D A715361B D911D9D 769C5729 82616866 EA2E3F0F 79813018 5527FECD A34B8237 8090AA9B 234FD2D3 1B88B8EB 5987FF26 16E599B2 3ED95B2F 49734A82 5C9DCC7D F8808370 5F90032C
  4A87F61C 5E397693 928701BA AA03F769 19A8CB10 582A9E81 4953C738 7AEA5D52 EA5660C FAEE9C6D 5918B4C 252D7D84 905C5281 1500BDA6 66163318 98670470 E2D4ABD7 132DBE04 C4AD5273 1D0D75A7 9262A848 3DA09756
  9F8A3B4 39B7BD9F 30547FF5 36367BCA 704EEF6A C7149AFA 4AD929BC 8A4D3B5F 16B4D21B 81FC4806 C7D48C1A 9120D43F 15B0948E 2FE957B1 70C74683 7C3A88D1 86255E13 7F5C2B1A BDD361C6 28A73A39 F8A46C42 9C2E5662
  B5D2837A CFCD9D39 D1D6AA0 F6EC835F CDA5A93D 9506FC6C 2DD3594D C461E17C 2AE9EF81 11C27755 10B70A38 6C0A10FA ABE468B2 9BFDE1CD 98EC36C9 C5FA9C2F D7C8A96D 66BD0895 731CD7C D4A45633 1441D9FF 3DB3A496
  7F0E91E3 1879A8CD F69E60DA C8B4ED63 F4F9D9DF 1181DDE2 E9D0A2D0 A7BEE0A2 78C2E4BD 7D9F0498 68134F47 344CDBD3 C822C0AA DE8BFA06 D298CB1A 364C35E3 9A7FB95D 6FDAB0A0 A78AF3BD D0294552 A22025EC F9074D63
  5EBA508F 891DD602 BDB60810 C962D785 2C749222 1F1F1EA6 3EEC3132 71E43C32 34DF1B43 F8D69A8F AC80675D 65A224FA B00CF0EB 3CF3A4D3 F1C03C06 73F69C6 D88689AD A2BA52ED 9327ED02 65BFAB7F C7884D33 3FACFB9E
  C01B87BF 2C9586C8 E27C5713 CABF773B A60621D2 FBB52F94 18E8E36B 85CB66C0 F5342CD5 C49F1B4F FAFA4584 16D45BDF 9BEA6F80 98FA564A 780771E2 13E95195 876904AD 72835F98 C4C33725 AE4377E7 97B31331 9BF8C92
  CCDA5CF3 1FD2DF42 8197A7DC C3F6612E F8E3A826 E7763883 A8E59F6D 95ADB7DC E42C4A69 60C0BFF9 8E1EB4D4 F6A670A1 7A66CD0A 37348B79 CF08A17B 18C46DA 1E9649F9 1935DEE4 DB95B81D 2674A9C6 4E9BB2C4 A3D32BC2
  39D335DB E262FA59 F70F6B8 B490705 50B484DF FCCC46FC A3D0486F A4212A7F 4F3388FB ACAC0EFC 7E87A794 1390EDFD B8570E41 26023E13 3C745D92 F998124A 7F0E8853 5B68057D 618E2D4B EB60746C CE816ACA F15E3A9C
  C902E697 33737D3E 9D222340 EEFE237E 537C0F2A 6ED7AFCF 70E8B751 C80D66AC 90AFB0E4 19B26683 7A51C39F 373BEC55 831C83A3 780EE07C 958CDE80 A06E984F C1852E25 7D65750A 5BA014BC C1026F4D 9CA6FE9D 977AD4BE
  ACE4B957 475B7BDE F27CD4B9 EF2CD86D 385F4931 F0910997 61C03872 252DCDA 7F42844 F724C002 E74C61E9 361CD1C5 E0D137C0 D2AA2C98 E808BDD1 99F2BD77 A0FF0482 43063C05 F4FFFA8B 63E77AB9 D2739C59 9EBD310F
  5BC67157 146B4D4 F38311FB C314CA3C 3EB9C172 67D7E7C 19B730F5 EE58BFB3 205AF992 546ED4B2 39762EF6 815D797C 497DB1E 3760DA5C 6F890346 7408A7EA 532F4592 BD3B8AAE 692053A6 A62DD744 859C84CD 356E412F
  150E50A9 77483AD4 34A90E76 85AB63E0 93DD8807 17C8AA15 4991FE25 52763513 71C3DBBC 2159DF4 93A8AAD2 C73031C2 CA331955 F16F59C7 875C5303 D9DA4E2C 40085FDC BE0ED630 B00DAA87 3B2F6671 8AD7657E EBF36045
  2D7174FD D452C6DC 2410C488 8B0F30E3 1C4876AE DA137584 AC84F4FE AD913CAA C55EDFD1 FD919ADC 3A983E84 F0261A6 B7093F98 2489C00D E13FDC13 191AB381 B4F3192E 6301D60B CAD733E E4D5D270 48021686 8D0D5A71
  DC7D1843 52052D2A D6CA8A96 471D52EF AAE687F5 168C5673 A2919F15 34DD0C30 781F00E3 F1EC7511 486F3F20 9C8773BD 745F790 9653B08B 7A18A9A0 931F5124 B6F0B07D C48E1BB1 9B35E6BB BD351956 D2297039 29D684A5
  68F614EF F602650 86C3C4C2 92496543 4D97D5C3 189BB221 78A03B9F 814EA1DD 54BF889A E7DEC99F 104FDC99 E44C6354 95FEB023 FB1C57C4 3E7DEE45 48F163AD 3F501623 E24E0C65 9BE41849 C446C257 4F1F2C47 FEAD51E2
  26F7FE7C 3EAEEE6C 158585A7 51E8E494 8F245282 2309F678 461AE813 2BD9FFD8 6372F0E9 28BED385 8CBD559A 420D190F 4440A348 B2B0091E EE504809 DE30DFB2 A1B90CD9 DA4D5063 37FC2E84 BF17885E A1190061 E67DA43A
  1F3A8089 BB49FEA0 8439D493 C7FEC59E DC3CCCD7 7276D68D 51D0CAD6 D7D87B19 E6E3848B DF377F39 AD1F08B3 98293870 8EF6FB92 E874B324 258713EF AEDC5BBF F0678B27 89509A02 4375749F F64CFE36 AB31593C 97891748
  A0D54E70 1C9C1071 E95A3C5A A9296471 2B322202 FCADC845 84DCEF36 6532648C A6B67136 69BAD630 3A8DF13E 619FB441 B41A2A32 B95703B9 7A22A5D0 F899CFF6 B87A9327 EA295FD9 FC29B143 F172C292 71840DBC F16FF9F8
  658F2D1E 43FB1D3F 116F2EA0 4C59F1BF 69F8F32A 7CD25106 DF79C64B D1C890A7 DF10971E D4A8D606 71F68C53 19E58502 A3FEB278 4CB02CE2 1BACD018 A5B1857 3DF13342 F4B48405 AEF2D639 5E916C44 85049B6C BE3463FB
  98186483 B8413331 517D861F 8E4BDE4F 6FEA1151 3464A997 C376C8FB E8D247FB 8D736ED1 52C79132 5487716B 23E2F2C1 8FC74F5 5BD45510 BC83B508 D4A8C9DA 2BE64CF0 95303421 E315C2D8 D7046095 216E97D1 876AA7D
  A5EED314 89500D1F 958920FA B6DA3ABC B8E86402 E846AF1E CC85B2A3 A77A8F62 C7353EC4 254B67D5 CC274320 ABBC256C A142E857 F358FCF2 B134735 24690A0B D9430CD5 9B81EC50 74B2C8CF DAD553E 5CE74801 FCD84930
  C1AA4456 BEE3CCB 84678E19 5A60BDDC 6AEFDD0 2E191C14 157CA435 41A813E0 BF701D97 27E595E1 A654E483 C899B772 5247B33 ABE2773E 453FC4D 6364CC7C 43230811 87306538 365F3A78 94764495 523063CB 478ED5EC
  7314053C 4EC78C25 4F7768C3 F3A85D3F 14EAF6C1 B2729A77 9ED36FB5 F0C5239E ED66E20A 2D9B7CEF E399577C E48B01A6 FEFA272C C9223BC0 279F8419 205795E9 C19408B1 9865A449 EBE6AB43 6999321D D50FFBC1 C01B722D
  FA7DD981 6BB97EE8 177B4B9C 172F222D 294F344D 1FE0ACE1 ADA10E31 DB5F3343 322236A9 484CE476 1D1DFE91 70C6F159 CA50FE62 F6466DA3 55716EBB CB698B03 883BF22C C20BDF80 C7EDB87E 22E8A430 1F71D136 D49915D1
  FD432EE7 632545F5 CF1E6925 476BF09E F3420DB7 5FDF7867 B71FF44A B3FE9EEA 27660309 85A866C4 848CADE5 C5EE5CEE 284EB4A3 C64E37B7 3A834F6F 8FA981AC 45EFAE6A 8108BA0 D39F795 1F15EF63 75FDEFA2 9EECD797
  76E3E8EA DAC2D54C 73EEB504 E01E5257 53161855 DFF5D1AB BD723097 4F8E1E7D 583103E 786BB1A 660455AB C0142195 B04017DE 82EE7D71 88ECBB5C FD9C1F72 497B4631 7094D08F 8F1A4B4D C16E2CC2 31632B4D 56D390AE
  365120D3 E3D93E94 8680D7ED FC038AEA 3C673F0B D7E7F776 73B4954D C0CC5E2E 1AD2E767 27BF28DC 95A8B07 60D1C65E EFBEF1EC F67E299D 33597E31 49796B63 BC4065B6 AD6244DE 78F3F4B1 39850AAF 3646621D F0C2DB60
  8C170443 57CE543A 7C010D7F 18FB47F7 ABC87012 3D48F03B C437EC84 4147EC44 19E4AFDC 29F7510 E2B677DC D9C0A28 B74F4B34 85846483 B8839033 F86AD049 C7C4C9D1 42B0A6A AD202B53 402903B7 36FFBC27 93F78627
  EE62ADF3 6D8D1710 83E971AB 83B17D6E F704310D C56F6765 FE0EE1D0 30B7EC5C 96DCFA06 8EEC89C1 49569109 AFC42880 76C23438 B4D97CE8 123FA053 DE319618 1C7F4D87 802E9E4A 3C54563F D067290 F405903D 93B30A66
  CA07374F 37BDEABE EF807D3D F3C712B3 B05A12D0 356023A7 5831328B 316AF569 FC6EED82 58DD4C3D D733B5AA CF5053B6 5EBC415B A0F12843 FF0496F1 110A9FC AFAD40D6 45DE6953 3C37347D EFDC509B 837FC635 A57C8E7A
  3D236352 9203966C 9E3EFD95 BDEB0B63 5D447938 646DF4B4 26FEB150 EA1730A5 E6132CA9 6B04C10D 350D5182 471A789E A561205F E83A5625 B288B17C 4D24CF02 864745EB 1B42BC02 BFC4B403 512FFA4B 84D023F5 CA5103E0
  316D41 D9C1BF6 992E99A1 F12FEDDD 8ED4F2E4 A86510C7 A098F6A9 E5626A84 5B4C81F4 87D444F8 7E212FBD 6BE5FB61 9CB625C6 26F0FBA5 24CF298A 8FB3028A 72037C4A 6FA082C2 2195CEEE 75177AEC AF695217 7A8605E6
  E2BEA28C 7773224D 8D29C8E3 87A055 89E96088 2F1A684D 24C4571C 669013BA 38DB945C F15B3A8D B5A2B532 7C0DE994 803DB11E C269374E 557FDB77 64BF1DC2 AEE478F 63D651A0 F81BDBB9 E2C06FB8 A8A8FCC0 2394E4FA
  B64382DF 33E07834 3993F4B1 CF8FE3 2141156B 7A91F03B AC646D54 667055E 8E8D5708 AB8C8B05 F3E80EE4 2399BA40 1E8FCCAA CE59A6C2 B052A3B7 DCDB1B7B E7498724 87332BF9 50538610 E06A0D49 CB1CFAC9 DCFE1996
  C840DD3A F9F1C9CF D7E202E1 D105963A A8D65A8D AE7603C6 4A64EFBF 1CB5DA2 24DB942B 957B7DF8 E99DE4F2 ADA2CB8F 3FD8E7FC 71B8B85 6FECC0B3 5CC77257 ACE7CDD9 6A09344B 6F7C0D83 AE690E85 6E7205C 15B13F1
  D29EA4C2 1DD89B6E CC74849A F222AA9D 1975262A 1D2BA12B BB57894E 6BD65227 DAE054C8 8ABEBEE2 4073EA03 AAA1D986 8E15B9A4 FEE0E0C8 F20A389A 34EC6E72 A64ABD2D 46765300 6A79CA46 779EC72B D5162FED 18A27A93
  49822C3D 48788C44 81DEB37B 69F01833 56604C16 381A1D0A 74531B36 3DF18E5A 145318E6 1D6C2496 391FE61E 7F0B23BC 2F3AF5B7 E4EFE2E6 46A87B44 A1F215D2 7C3F50F5 AB19A1BC 5EBB429E 492437A7 4AC83840 B735E7D2
  3525BCAC 9549DB05 79E767FF F05D8231 6C43D8F4 F727C0B4 17A770AF 447BF315 A67B9F1D ECA48163 BA581343 3E47E6FF 1BA280E4 B781B3D2 764F5A78 E1D27607 A230B4B2 2AF6B9DD 5291053D B09BD304 6C9E06C 59D04CB2
  EE3C0B3B 6653BB69 305C42C2 8B97E12F 26D29687 A58205E4 F9F0E53D 84502420 35EA9B63 7E9970DD 7ECEC3E4 3AE0611C 32DD0FF9 BA0D9AEF F481D555 97E7FCFD 2E0AB5A F00E7AE9 361795EA 2E55DA01 194C9A1D 136D574A
  7E14FACE DE7A91F8 453D93CE EF846B4A 26790712 E4645932 B7560E7A 47547EAF 75E7D492 16108454 664EC34E EB6433B9 B402CD78 539449BB C924BA79 BF5E4A4B 14BD87AB 16B1D88B 577C1ED4 9F07CDDB 98FE9A1C 5ACAFBC6
  FFB5C11E A05581F7 1DDCDEBA C9B328CB E9DF12EF 14F1AA 24439FEE 4CBFEDE9 2F7D2EE7 B7370B1B CF3D1888 45A7171D 31D0DD3C 6B349E2 5582017A A370E9AB D660CE97 EBAF4DA2 E19AD39 5BB804D0 37CF3FFE 22815F9C
  AA713EDE 3C3004C0 96019536 E8ABFF00 B75101E 3DA53B48 9789D4F8 75BF294A BBCBCB58 4C0FAC0A D15177D4 BE374678 263D9747 EE3EBAD5 4F77F834 247ABCC 31E8FDF3 BDD4247A BC88B019 B40A4946 82DDB3BB 88763A09
  5704E943 ED3513D4 1C87F452 210CA25C 6427CFCB A021DF04 B4D0E1A0 8C0D15EB 1B7D20E9 FB2F4A23 740D3ACD C428B3C2 B785C0CC F546B4C1 6EE4BC1F 4FD93A8B E4DEF886 91058609 C899DBB5 93F8D8A3 4F13E5C1 49F3FBB8
  1E46DD6C BB911FE9 B7002E9A E7CD7AC3 BA96C96 FC0322D3 D576CEB0 B0954FF1 4F305103 9DD74439 2631A757 EB471B59 146E73CF 96FEB51F B35BD3 7DB7BFB6 8940025F B586899F 368921D0 E02EDD78 A31EE1B6 E6DBF99D
  34930296 BC401002 26C263E5 F0DFC50 7D670BD8 2ECEBD04 394B46E6 4CCF1748 A92E23A9 1A7252C6 E0F2852F 5835491F CB80B9CA 31AB0296 699778C7 F474E02C 3875C38E 67297CDA F8D17A54 6F69BAF5 B8A47CCB CD29069C
  BE36C634 E981C687 1CC1D629 C0360F77 B39822E6 8F18A728 2CA6D704 DFA8C1A 7581E5CE 26AA8836 20B27AE6 DEDE0D5D 63DD6719 701D8F01 F1391D8A F012F3D3 744A97A0 5BC52D42 8486B3A1 FB019F4A 29FBEB07 BDD06AF8
  4FE9295B 1CCCA7E0 62B79D23 885F903E 1D9D212 9F7995C6 F7486B6D 49514681 DC227478 BFB13E6F C2016736 DE0B7C66 55BA0489 E2AF4B82 848FCD01 2B980A49 3411E6AA 1BF859A2 54E5DA89 FC372F86 6B656AC7 8ADD7146
  412A34CE D145B850 4CEC0A85 439B9911 1CBD6D74 B969C190 3F677F4A CCB06909 F6C5A43F 3B9B6332 787518DC 4600D7F2 80446AD6 B40EEA20 C3A808B C8B76F51 527581EC 9101A9E0 CAEB1AC7 AF9B471A EA59C20A D8743BDA
  9EE19358 85D117E0 69A6E557 965B51A5 8B94ECDA CC4384FB DE6AFE66 D5337EA5 B8E7D1EE 24D9F78 10FF0300 5BBD79C9 4F2D270D 3A78BD8A 78D6235F BB1F8532 765772F5 4F1D05FF D040D307 5A7A84BC C735D190 E047353C
  9DEAE4C7 C5F7AD1D 7DEFEC3 5DAE9EE 7B55A6FC 424CEA30 4D787CD0 844ADB0B CBB063FB D5FF2105 348E8703 ADECBB59 65E2D80F 6F19C93A 55277579 615022AF C7FC6593 19ADC42C D6E2DD24 71BC0E80 67848546 440B2630
  FD2E5744 22E38F5C A6241022 85ED9C72 1AA8DA72 7EFA0AD5 C6EC85EC EFEEF8A7 104D7EA2 23A34C2D 4948929E 8624D4DC 2D6F26AB 2D83ECB9 13CA0E87 287866A E69FDF1C 15821099 EB29EA0D 9C5C0B39 15A843EB 286C98A3
  5D958299 EC10DD93 C784326C 546C49A0 61F38626 527AE9F1 84A988B3 7576F216 46996128 AB0A926C FE902D96 E10686A9 B3CFABB1 81D7B82A F2C6F138 83694CE4 67CB578C 4263CB4 1FF49DD0 AC4D9F4A EF8319BD 973D4AA2
  E4CDECA3 5FEFD6A 9A7085AB 6E80995A AF9B1ABB 959CF18D 73F91B4A E9CC0E76 85222D57 6EF0B0A1 87595F33 596D24EF F09DD5F9 604E3107 566ACC53 70C8FCDA FF3793FE 95495B4D 2453309B 54C0F991 BCC5C7CE EF63907F
  4C4FA92 2DF6E2F6 38BE3F59 A5E9EC9A C3A27FB 52273EBD 5E7C899E 503728C2 EC85FC0E 4CB34866 107BE82F 1E3FFBDD B47D287 B48786FC 846EACD D65A77B9 61BB4F83 6B49460D A99A3F7 B680A4C6 6958CB45 5BEDE295
  134E3667 9CEBE5FB 4881E2DE D234E537 490C0A4D FD19E73 BF0C6C48 B9E73ACD 54E44916 C94D3FEB 8F369E4A 2638E0E5 1B6968B3 FFC77185 7D805560 A7BDBF69 D49649A6 15F04082 C68CADF6 604EE760 50D4286A 9B32D8B
  B741369 BC2FF52F 4FA7E22D 6088180B 313D8B5B 2FF532B2 C9A48F13 ECEA2A5 D0C8EA95 578764A2 4F3D4AC8 5EB6080F 1E0A0E03 AE716590 FFEB0CC7 6FE1EB7 C5B593B2 66D432C5 37F06AF2 6831D2B9 D1BBFFF1 5AA72033
  76F25AEA 71479278 21FF9EC3 AA488FF0 81547538 39489604 A49CB474 67FC5FEE B6E25F5C 641A098A 21E508D1 2748A945 E2B54D4 6E1BD64 739ACE93 1BD20A0F CD3707E0 B38C8478 6ACD37FE 49CF85C 7C31B8E3 3C193701
  C4942781 A7F85524 3D6CF190 5F03324D 7245974B E18BB334 E7813DD4 B48367F9 C402B631 1EFA597 27C7D20A 296723FE 53E54135 A0DA4504 4628E77F 72E0CCC2 CCDE5DBC 27DFBA45 112D6EB0 6D1B5D52 9AB29B1D 76948EE2
  377121D3 56CF7638 4C0B55E9 624883BF 972F78A3 9A28C68D AE90D24 7EAC9C A9A6E4DB DE24AE2F 448CD762 88E5F22C A583EC6C 8ED3EC4C 3E89BF72 D86BAC8D CC845E28 E0C369A EE2AA557 45BD4A B20AA73 64764596
  679255C9 201011E6 11C23292 A7F9380A D7AF9D23 110CFCC4 521457D 7A58C546 1A379750 E53C1CCF B63A9D7E 3C07AC41 A6F46315 273E11FD 927E7C6F 562F4000 4FB28981 F75619F9 52B88E35 4E99F980 809BBA44 E455148E
  9ABC4643 25C8810A E20D28E6 B4FCD8ED 8A3C026 D37CB246 5CFB992D 786FFED5 96870AB5 185B6076 490729A6 40720333 B11A9B1C 64F4A739 47A536C5 AD4D44E 8A4BA4B4 FB68D2EF AFBE8F39 6CFB3DB0 D504558B 89845A5B
  F119BC0A 9ABC8E09 B9EC492D 6F3B31F9 E3FA417F EB1C4BB5 B1B3AFF2 C3DFC409 8BF05DC2 77FB448E F4B1232C 1A987ABC 4693A6C 7B3DF0C9 B47F84D5 9B0A4EB5 5D574817 DB50F975 4AD4298F 3A667374 69EF4C17 2CE6325B
  6F3174D2 5DE2040F 48CB17F0 CC74EECE 1E461AD2 BC8E5806 9DBC8762 402E4E5F C8EF3851 6B65C569 A2EFE1F1 A70C52DB FC116BA9 FF0E5296 C59C881A D53DB04D E664F43E DA3D2AD5 F6EC613E C5F5AE50 B7A0136F 756B6531
  A29B778F 110F3967 BEF3D0EF FAEAE4BB 9FFB45C8 DFAD778 C82BC861 87AC4D28 40FD870E A3B06BD4 AA3B9FC8 FF0750B8 5C1BE67F B4176C29 19DC9761 DE299F0F 45EC46B7 41FFB4CF E7578A1E AF6D5CDB 7D3796E8 EE0B3726
  E10C377F 747FE839 7DFEF17F D8861ECA 71C26D10 358291E1 B3C821EF 5668AAD2 DABF4688 988BC581 6182D14 33F75F3F 86DB7138 24369714 3FDA6E94 F6EDDADB 4B1FBEBB E93CDB42 B146255C C83F786A 965608DB 56066E88
  E0A04E87 3213F7E5 BB853286 792FD4B2 1501D317 9DF3D289 9A8E0772 318A61AA 33A0198E C17153A7 507E0C17 BC80637 C73CCC66 EA55C7C5 F9869C3D 135095D0 5479866C F2B77D75 FC821CF0 F5BA0E27 5C5129F0 4B4D7684
  91978FB2 60BC5A46 F441F68 82B99D71 10B5160C D1BC38DF C8CD0336 D78207C3 B32B4E7E 2505C92C 7EA681B 63C278E8 9CC25E09 BA806AF2 AF5614C3 83464810 717DB28F ACAD6C1C 5A5FF1ED FF5300F4 56A5DE4C BD5D9A94
  102B80AA 4F4881CF FD253C21 E44C1BA4 325F8C40 7F0F3A90 7F295FB1 4620FB29 87E502A7 C084FFA EF56227 69584FA9 312A919D 5A47F96C DC599E7F 2CA6E8C C7C19D6B 363F2090 37B6B40D 207CEFFA E2B82613 46BDACA7
  BBAB106C DC9E4114 32620E06 5E9D9364 275DAF89 2BDDE27A 65DC22F3 C8D4CE77 D27831F8 8C960353 7339E4F3 3D481660 8562F337 769FB98E 32911F66 CAD11698 C8B183E7 DFF519AC ADBF30F6 9E1FFFBD 8E5C867A 14962C0C
  5D9F617E 80EB20A4 C31D62EE EC9A1AB1 3EC6CB61 7FA74609 380A719 3FF14EC0 A10E4C44 E4A388EE 42CFCDA5 9403C92E 9B19034D F80FBD5A 7A40E77F 4E7EF42A 4B3A1FAD 98A60141 D6D8E2A5 29FF9ED DE403604 8616BDD5
  8E35191D 6414C06C C6DFEE0 F0D9E612 E00CA8C8 BB25EFF9 1E177BA5 4D45E689 C1FD18EF 56E74399 D4347101 7EFBD1DA 5D356F50 CC771C4B 9B83ACA3 4FC2FA30 C80F508D 266BEED8 88DE599C 7BEF9A9 980B184A D8540C4
  F0A2064A 1D215CEC D1A68C9 FC465A9E 8BEE75CD 2F0F02D8 CE50A418 6B52F6A5 CFCBDCA5 D5BF09E0 63BA6C27 D204C2FB 2951BBC6 A4C71FFB A1F43295 4D78E39A A4AE3B7D B97C8582 63E60A07 6B815810 76BA7D4B 77D44C7E
  8DAD5CF5 C9F0F735 A44E4332 7BAB92BA FD3BE1EB E45D0CE5 7C323E21 4285F0C8 935108AD AAAB19A2 1EB30921 25971B0 4E190A18 D4E491AB F841EEE5 EA874EBC 998F2044 35801654 236A4C85 C1D3BC29 8FF23F0 75428EDB
  25F85723 170F7063 6951E311 4B905519 D710E5C8 6BD543AB 65B59515 C5CAAE4D CB3ED6F9 A29E61E6 70BA174A 49B1CBBE 25EFB80E 19DD45 F53CF307 A17463A9 B194448A)")))

;;; If several calls to inithex() occur, it needs to decide based on the _last_
;;; call, not the first, whether the SCRAMBLE array is needed.
(with-test (:name :bob-jenkins-bug :skipped-on (:not :slow))
  (let* ((input (coerce *very-slow-example*
                        '(array (unsigned-byte 32) (*))))
         (lambda (sb-c:make-perfect-hash-lambda input))
         (fun (compile nil lambda)))
    (test-perfect-hashfun fun input)))

;;; The 32-bit code generator is supposed to emit fewer and smaller instructions
;;; than the compiler would, particularly when TAB and SCRAMBLE arrays are needed.
;;; But sometimes it emits worse code, so I'm not ready to say it's usable.
#|
Good example:
(LET ((B (& (>> VAL 8) 7)))
  (LET ((A (>> (<< VAL 5) 29)))
    (^ A (AREF TAB B))))
Before:
; Size: 59 bytes. Origin: #x5515E416
; 16:       8BDA             MOV EBX, EDX
; 18:       C1EB08           SHR EBX, 8
; 1B:       83E30E           AND EBX, 14
; 1E:       488BCA           MOV RCX, RDX
; 21:       48C1E105         SHL RCX, 5
; 25:       48230DC4FFFFFF   AND RCX, [RIP-60]                ; [#x5515E3F0] = #x1FFFFFFFE
; 2C:       48C1F91D         SAR RCX, 29
; 30:       4883E1FE         AND RCX, -2
; 34:       488BD3           MOV RDX, RBX
; 37:       48D1FA           SAR RDX, 1
; 3A:       488B059FFFFFFF   MOV RAX, [RIP-97]                ; #(0 11 8 1 ...)
; 41:       0FB6441001       MOVZX EAX, BYTE PTR [RAX+RDX+1]
; 46:       D1E0             SHL EAX, 1
; 48:       488BD1           MOV RDX, RCX
; 4B:       4831C2           XOR RDX, RAX
After:
; Size: 43 bytes. Origin: #x55170C86
; 86:       488BC2           MOV RAX, RDX
; 89:       48D1E8           SHR RAX, 1
; 8C:       8BC8             MOV ECX, EAX
; 8E:       C1E908           SHR ECX, 8
; 91:       83E107           AND ECX, 7
; 94:       8BD8             MOV EBX, EAX
; 96:       C1E305           SHL EBX, 5
; 99:       C1EB1D           SHR EBX, 29
; 9C:       488B05BDFFFFFF   MOV RAX, [RIP-67]                ; #(0 11 8 1 ...)
; A3:       0FB6440801       MOVZX EAX, BYTE PTR [RAX+RCX+1]
; A8:       31D8             XOR EAX, EBX
; AA:       488D1400         LEA RDX, [RAX+RAX]

Tolerable example: (& (+ (>> VAL 13) (>> VAL 24)) 7)
Before:
; Size: 28 bytes. Origin: #x5516B676
; 76:       488BCA           MOV RCX, RDX
; 79:       48C1F90D         SAR RCX, 13
; 7D:       4883E1FE         AND RCX, -2
; 81:       48C1FA18         SAR RDX, 24
; 85:       4883E2FE         AND RDX, -2
; 89:       4801CA           ADD RDX, RCX
; 8C:       83E20E           AND EDX, 14
After:
; Size: 24 bytes. Origin: #x5516B706
; 06:       488BC2           MOV RAX, RDX
; 09:       48C1E80E         SHR RAX, 14
; 0D:       8BC8             MOV ECX, EAX
; 0F:       C1E90B           SHR ECX, 11
; 12:       01C1             ADD ECX, EAX
; 14:       83E107           AND ECX, 7
; 17:       488D1409         LEA RDX, [RCX+RCX]

Bad example: (& (- VAL (>> VAL 23)) 7)
Before:
; Size: 20 bytes. Origin: #x55178AA6
; A6:       488BCA           MOV RCX, RDX
; A9:       48C1F917         SAR RCX, 23
; AD:       4883E1FE         AND RCX, -2
; B1:       4829CA           SUB RDX, RCX
; B4:       83E20E           AND EDX, 14
After:
; Size: 25 bytes. Origin: #x55178B36
; 36:       488BC2           MOV RAX, RDX
; 39:       48D1E8           SHR RAX, 1
; 3C:       8BC8             MOV ECX, EAX
; 3E:       C1E917           SHR ECX, 23
; 41:       8BD8             MOV EBX, EAX
; 43:       29CB             SUB EBX, ECX
; 45:       83E307           AND EBX, 7
; 48:       488D141B         LEA RDX, [RBX+RBX]
|#

#+nil
(defun test-uint32-arithmetic (lambda inputs print &optional (n-random-inputs 100))
  ;; As ugly as it is to have all the FIFTH and THIRD here,
  ;; it works because LAMBDA has a known shape which is always this
  ;; possibly without symbol macros -
  ;;  (LAMBDA (VAL)
  ;;    (DECLARE (OPTIMIZE ...))
  ;;    (DEC:ARE (TYPE ...))
  ;;    (SYMBOL-MACROLET # (THE (MOD n) (UINT32-MODULARLY VAL forms ...))))
  ;;
  (let ((tables)
        (maybe-tables (fifth lambda))
        (random-state (make-random-state t))
        (calc))
    (when print
      (format t "~A~%" lambda))
    (let ((cast (cond ((eq (car maybe-tables) 'symbol-macrolet)
                       (setq tables (cadr maybe-tables))
                       (third maybe-tables))
                      (t
                       maybe-tables))))
      (assert (eq (car cast) 'the))
      (assert (eq (caadr cast) 'mod))
      (let ((expr (third cast)))
        (assert (eq (car expr) 'sb-c::uint32-modularly))
        (assert (eq (cadr expr) 'sb-c::val))
        (setq calc (cddr expr))))
    (multiple-value-bind (steps n-temps)
        (sb-c:phash-renumber-temps
         (sb-c:phash-convert-to-2-operand-code calc tables))
      (when print
        (let ((*print-readably* t))
          (format t "tables=~X~%calc=~A~%n-temps=~D~%steps=~A~%"
                  tables calc n-temps steps)))
      (let* ((f (compile nil lambda))
             (f-inst-model (get-simple-fun-instruction-model f))
             (g (compile nil
                         `(lambda (x)
                            (declare (optimize (safety 0) (debug 0)))
                            (sb-vm::calc-phash x ,n-temps ,steps))))
             (g-inst-model (get-simple-fun-instruction-model g))
             (predicted-best
              (if (or tables (> (phash-count-32-bit-modular-ops calc) 1))
                  'g ; predict that G is better
                  'f)) ; predict that F is better
             (actual-best
              ;; If they're the same number of instructions, the tie counts
              ;; as a win for 32-bit math because code size is always smaller.
              ;; So F has to be strictly shorter to win.
              (if (< (length f-inst-model) (length g-inst-model))
                  'f
                  'g)))
        (when (or print (not (eq predicted-best actual-best)))
          (format t "~&DEFAULT COMPILE:~%")
          (disassemble f)
          (format t "~&32-BIT MODULAR ARITH COMPILE:~%")
          (disassemble g)
          (terpri)
          (unless (eq predicted-best actual-best)
            (error "Wrong prediction, expected ~S best for~%~S"
                   predicted-best lambda)))
        (flet ((try (input)
                 (unless (eql (funcall f input) (funcall g input))
                   (error "functions disagree on ~X: ~X ~X"
                          input
                          (funcall f input)
                          (funcall g input)))))
          (map nil #'try inputs)
          ;; Test the behavior on random inputs
          (dotimes (i n-random-inputs)
            (try (random (ash 1 32) random-state))))
        (values actual-best n-temps
                ;; size delta
                (- (primitive-object-size (sb-kernel:fun-code-header g))
                   (primitive-object-size (sb-kernel:fun-code-header f)))
                ;; instruction count delta
                (- (length g-inst-model) (length f-inst-model)))))))

;;; This tested the 32-bit code generator, but now that it's enabled,
;;; the perfect hash function itself it tested (in COMPILE-PERFECT-HASH) which means
;;; that both the function and the codegen have to be correct.  But I still want to
;;; keep the logic that guesses whether 32-bit untagged arithmetic in UNSIGNED-REG
;;; is better than arithmetic on tagged words.
(with-test (:name :32-bit-codegen :skipped-on :sbcl)
  (flet ((test-file (filename)
           (let ((tests (with-open-file (f filename)
                          (let ((*read-base* 16)) (read f))))
                 (wins 0))
             (dolist (testcase tests)
               (sb-int:binding*
                   ((inputs (coerce (car testcase) '(array (unsigned-byte 32) (*))))
                    (lambda (sb-c:make-perfect-hash-lambda inputs))
                    ((winner n-temps) (test-uint32-arithmetic lambda inputs nil)))
                   (assert (<= n-temps 3))
                   (when (eq winner 'g)
                     (incf wins))))
             (let ((n-trials (length tests)))
               (format t "32-bit modular vop wins ~d/~d times (~,,2F%)~%"
                       wins n-trials (/ wins n-trials))))))
    (mapc #'test-file
          '("../xperfecthash30.lisp-expr"
            "../xperfecthash63.lisp-expr"
            "../xperfecthash61.lisp-expr"))))

;;; Complicated expressions can be compiled much more concisely using the 32-bit modular
;;; math vop because it removes instructions that mask intermediate results to
;;; (FIXNUMIZE #xFFFFFFFF) or restore the fixnum tag following a right-shift.
#|
;;; Before:
; Size: 130 bytes
; 19:       48030DD0FFFFFF   ADD RCX, [RIP-48]                ; [#x10032D88F0] = #x17E57E524
; 20:       48230DD1FFFFFF   AND RCX, [RIP-47]                ; [#x10032D88F8] = #x1FFFFFFFE
; 27:       488BD9           MOV RBX, RCX
; 2A:       48C1FB10         SAR RBX, 16
; 2E:       4883E3FE         AND RBX, -2
; 32:       4831D9           XOR RCX, RBX
; 35:       488BD9           MOV RBX, RCX
; 38:       48C1E308         SHL RBX, 8
; 3C:       48231DB5FFFFFF   AND RBX, [RIP-75]                ; [#x10032D88F8] = #x1FFFFFFFE
; 43:       4801D9           ADD RCX, RBX
; 46:       48230DABFFFFFF   AND RCX, [RIP-85]                ; [#x10032D88F8] = #x1FFFFFFFE
; 4D:       488BD9           MOV RBX, RCX
; 50:       48C1FB04         SAR RBX, 4
; 54:       4883E3FE         AND RBX, -2
; 58:       4831D9           XOR RCX, RBX
; 5B:       8BD9             MOV EBX, ECX
; 5D:       C1EB08           SHR EBX, 8
; 60:       81E3FE010000     AND EBX, 510
; 66:       488BF1           MOV RSI, RCX
; 69:       48C1E60D         SHL RSI, 13
; 6D:       48233584FFFFFF   AND RSI, [RIP-124]               ; [#x10032D88F8] = #x1FFFFFFFE
; 74:       488D1431         LEA RDX, [RCX+RSI]
; 78:       48231579FFFFFF   AND RDX, [RIP-135]               ; [#x10032D88F8] = #x1FFFFFFFE
; 7F:       48C1FA17         SAR RDX, 23
; 83:       4883E2FE         AND RDX, -2
; 87:       488B0552FFFFFF   MOV RAX, [RIP-174]               ; #(77 927 238 ...)
; 8E:       0FB7441801       MOVZX EAX, WORD PTR [RAX+RBX+1]
; 93:       D1E0             SHL EAX, 1
; 95:       4831C2           XOR RDX, RAX
;;; After:
; Size: 69 bytes
; 06:       48D1EA           SHR RDX, 1
; 09:       81C292F22BBF     ADD EDX, -1087638894
; 0F:       8BC2             MOV EAX, EDX
; 11:       C1E810           SHR EAX, 16
; 14:       31C2             XOR EDX, EAX
; 16:       8BC2             MOV EAX, EDX
; 18:       C1E008           SHL EAX, 8
; 1B:       01C2             ADD EDX, EAX
; 1D:       8BC2             MOV EAX, EDX
; 1F:       C1E804           SHR EAX, 4
; 22:       31C2             XOR EDX, EAX
; 24:       8BC2             MOV EAX, EDX
; 26:       C1E808           SHR EAX, 8
; 29:       0FB6C0           MOVZX EAX, AL
; 2C:       8BCA             MOV ECX, EDX
; 2E:       C1E10D           SHL ECX, 13
; 31:       01CA             ADD EDX, ECX
; 33:       C1EA17           SHR EDX, 23
; 36:       488B0DA3FFFFFF   MOV RCX, [RIP-93]                ; #(77 927 238 ...)
; 3D:       0FB74C4101       MOVZX ECX, WORD PTR [RCX+RAX*2+1]
; 42:       31D1             XOR ECX, EDX
; 44:       488D1409         LEA RDX, [RCX+RCX]
|#
(with-test (:name :32-bit-codegen-big :skipped-on :sbcl)
  (with-open-file (stream "../tools-for-build/unicode-phash.lisp-expr")
    (loop
     (let ((keys (let ((*read-base* 16)) (read stream nil))))
       (unless keys
         (return))
       (let ((lexpr (let ((*package* (find-package "SB-C"))) (read stream))))
         (multiple-value-bind (actual-best n-temps size-delta inst-count-delta)
             (test-uint32-arithmetic lexpr keys nil 1000000)
           (assert (eq actual-best 'g))
           (assert (<=  n-temps 3))
           (format t "delta=(~D bytes, ~D insts)~%"
                   size-delta inst-count-delta)))))))


(defvar *bug-2055794-test-form*
  '(case x
    ((#\g 5) 1)
    ((#\} #\j #\y #\$) 2)
    ((#\- #\|) 3)
    ((#\X) 4)
    ((0 7 4 #\% 3) 5)
    ((#\{) 6)
    ((#\l) 7)
    (t 'dropthru)))

(defun bug-2055794-tester (x) #.*bug-2055794-test-form*)

(with-test (:name :lp-2055794)
  (dolist (clause (butlast (cddr *bug-2055794-test-form*)))
    (dolist (key (car clause))
      (let ((answer (bug-2055794-tester key)))
        (assert (eq answer (second clause))))))
  (dolist (key '(foo bar baz))
    (assert (eq (bug-2055794-tester key) 'dropthru))))

(defun f340 (p1)
  (position p1 '(string #:g4389630 #:|AABb|)))
(compile 'f340)
(with-test (:name :lp-2056341)
  (assert (eq (f340 0) nil)))

(with-test (:name :assoc-warn-list-seek-not-optimized
                  :skipped-on (not :64-bit))
  (let ((*error-output* (make-string-output-stream)) (note 0))
    (handler-bind ((sb-c::perfect-hash-generator-failed
                    (lambda (c) (declare (ignore c)) (incf note))))
      (compile nil
       '(lambda (x)
         (declare (optimize (sb-c:jump-table 2)))
         (assoc x '((0 . #\f) (1 . #\b) (100 . #\a) (600 . #\w) (601 . #\h) (700 . #\z)
                    (#xffffffff . 0) (#x1ffffffff . 1)))))
      (assert (= note 1))
      (compile nil
       '(lambda (x)
         (declare (optimize (sb-c:jump-table 2)))
         (member x '(0 1 100 600 601 700 #xffffffff #x1ffffffff foo 3 4))))
      (assert (= note 2)))))
